package com.zhuj.logic;

import com.zhuj.client.proxy.NrpcInvocationHandler;
import com.zhuj.core.entity.ServerResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Condition;

/**
 * Created by Administrator on 2018/1/4.
 */
public class ProcessRunnable implements Runnable {

    private static final Logger LOG = LoggerFactory.getLogger(ProcessRunnable.class);

    private ConcurrentMap<Integer,Object[]> invocation = new ConcurrentHashMap();

    private LinkedBlockingQueue<ServerResponse> resultQueue = new LinkedBlockingQueue<ServerResponse>();

    private volatile boolean isRun = false;

    public void putInvocation(Integer id,Object[] invoc){
        invocation.put(id,invoc);
    }

    public Object[] getInvocation(Integer id){
        return invocation.get(id);
    }

    public boolean removeInvocaHandler(Integer id){
        Object o = invocation.remove(id);
        if (o == null) return false;
        return true;
    }

    public void produce(ServerResponse response) throws InterruptedException {
        resultQueue.put(response);
    }

    public void run() {
        isRun = true;
        while (isRun){
            try {
                ServerResponse response = resultQueue.take();
                Integer id = response.getResponseId();
                NrpcInvocationHandler nih = (NrpcInvocationHandler) getInvocation(id)[0];
                Condition condition = (Condition) getInvocation(id)[1];
                if (nih != null){
                    if (response.getError()!=null){
                        nih.setResult(id,response.getError());
                        LOG.error(response.getError());
                        throw new Exception(response.getError());
                    }else{
                        nih.setResult(id,response.getResult());
                    }
                    nih.signal(condition);
                    if (!removeInvocaHandler(id)){
                        LOG.error("invocation remove defeat! condition: {}",condition);
                        continue;
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
